package cn.com.cetccst.mdm.engine;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.tdtech.devicemanager.ApplicationPolicy;
import com.tdtech.devicemanager.ContainerPolicy;
import com.tdtech.devicemanager.DevicePolicyManager;
import com.tdtech.devicemanager.LocationPolicy;
import com.tdtech.devicemanager.PeripheralPolicy;
import com.tdtech.devicemanager.SecurityPolicy;
import com.tdtech.devicemanager.TelephonyPolicy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import cn.com.cetccst.tools.log.CommonLogger;
import ga.mdm.PolicyManager;

public class TdMdmEngine extends BaseMDMEngine {
    String TAG = TdMdmEngine.class.getSimpleName();
    private PeripheralPolicy mPeripheralPolicy;
    private ApplicationPolicy mApplicationPolicy;
    private TelephonyPolicy mTelephonyPolicy;
    private SecurityPolicy mSecurityPolicy;
    private LocationPolicy mLocationPolicy;
    private ContainerPolicy mContainerPolicy;
    DevicePolicyManager mDevicePolicyManager;
    private PolicyManager gaPolicyManager;
    private android.app.admin.DevicePolicyManager dpm;
    PolicyManager mPolicyManager;

    public TdMdmEngine(Context context) {
        super(context);
        mPolicyManager = PolicyManager.getInstance();
        mDevicePolicyManager = DevicePolicyManager.getInstance(context);
        mPeripheralPolicy = mDevicePolicyManager.getPeripheralPolicy();
        mApplicationPolicy = mDevicePolicyManager.getApplicationPolicy();
        mTelephonyPolicy = mDevicePolicyManager.getTelephonyPolicy();
        mSecurityPolicy = mDevicePolicyManager.getSecurityPolicy();
        mLocationPolicy = mDevicePolicyManager.getLocationPolicy();
        mContainerPolicy = mDevicePolicyManager.getContainerPolicy();
        gaPolicyManager = PolicyManager.getInstance();
        dpm = (android.app.admin.DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
    }

    @Override
    public boolean setActiveDeviceAdmin(Activity activity) {
        Intent intent = new Intent(android.app.admin.DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
        intent.putExtra(android.app.admin.DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminComponent);
        //intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, getString(R.string.add_admin_extra_app_text));
        activity.startActivityForResult(intent, 10000);
        return true;
    }

    @Override
    public void controlBluetooth(boolean disabled) {
        mPeripheralPolicy.enableBluetooth(!disabled);
    }

    @Override
    public boolean isBluetoothControlled() {
        return !mPeripheralPolicy.isBluetoothEnabled();
    }

    @Override
    public void controlCamera(boolean disabled) {
        mPeripheralPolicy.enableCamera(!disabled);
    }

    @Override
    public boolean isCameraControlled() {
        return !mPeripheralPolicy.isCameraEnabled();
    }

    @Override
    public void controlWifi(boolean disabled) {
        mPeripheralPolicy.enableWifi(!disabled);

    }

    @Override
    public boolean isWifiControlled() {
        return !mPeripheralPolicy.isWifiEnabled();
    }

    @Override
    public void controlMicroPhone(boolean disabled) {
        mPeripheralPolicy.enableRecord(!disabled);
    }

    @Override
    public boolean isMicroPhoneControlled() {
        return !mPeripheralPolicy.isRecordEnabled();
    }

    @Override
    public void controlExternalStorage(boolean disabled) {
        mPeripheralPolicy.enableUsbMassStorage(!disabled);
    }

    @Override
    public boolean isExternalStorageControlled() {
        return !mPeripheralPolicy.isUsbMassStorageEnabled();
    }

    @Override
    public void controlScreenShot(boolean disabled) {
        gaPolicyManager.setCaptureScreenPolicies(disabled ? 0 : 1);
    }

    @Override
    public boolean isScreenShotControlled() {
        return gaPolicyManager.getCaptureScreenPolicies() != 1;
    }

    @Override
    public void controlNFC(boolean disabled) {
        if (!disabled) {
            mPeripheralPolicy.allowNfc();
        } else {
            mPeripheralPolicy.disableNfc();
        }
    }

    @Override
    public boolean isNFCControlled() {
        return !mPeripheralPolicy.isNfcAllowed();
    }

    @Override
    public void controlMobileHotSpot(boolean disabled) {
        mPeripheralPolicy.enableWifiAp(!disabled);
    }

    @Override
    public boolean isMobileHotSpotControlled() {
        return !mPeripheralPolicy.isWifiApEnabled();
    }

    @Override
    public void controlCallout(boolean disabled) {
        mTelephonyPolicy.enableTelephone(!disabled);
    }

    @Override
    public boolean isCalloutControlled() {
        return !mTelephonyPolicy.isTelephoneEnabled();
    }

    @Override
    public void controlSms(boolean disabled) {
        mTelephonyPolicy.enableSms(!disabled);

    }

    @Override
    public boolean isSmsControlled() {
        return !mTelephonyPolicy.isSmsEnabled();
    }

    @Override
    public void controlMobileData(boolean disabled) {
        if (!disabled) {
            mPolicyManager.setDataConnectivityPolicies(2);
            Log.e(TAG, "release mobileData via TD API");
        } else {
            mPolicyManager.setDataConnectivityPolicies(0);
            Log.e(TAG, "restrict mobileData via TD API");
        }
    }

    @Override
    public boolean isMobileDataControlled() {
        int mode = mPolicyManager.getDataConnectivityPolicies();
        if (mode == 0) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public void controlVolumeDown(boolean disabled) {
        if (!disabled) {
            mPolicyManager.setVolumeAdjustDisabled(false);
            Log.e(TAG, "release record via TD API");
        } else {
            mPolicyManager.setVolumeAdjustDisabled(true);
            Log.e(TAG, "restrict record via TD API");
        }
    }

    @Override
    public boolean isVolumeDownControlled() {
        return !mPolicyManager.isVolumeAdjustDisabled();
    }

    @Override
    public void controlAutoTime(boolean disabled) {
        gaPolicyManager.setUserTimeMgrPolicies(disabled ? 0 : 1);
    }

    @Override
    public boolean isAutoTimeControlled() {
        return gaPolicyManager.getUserTimeMgrPolicies() != 1;
    }

    @Override
    public void controlUsbData(boolean disabled) {
        mPeripheralPolicy.enableUsbMassStorage(disabled);

    }

    @Override
    public boolean isUsbDataControlled() {
        return !mPeripheralPolicy.isUsbMassStorageEnabled();
    }

    @Override
    public void controlUsbDebug(boolean disabled) {
        mPeripheralPolicy.enableUsbDebugging(!disabled);
    }

    @Override
    public boolean isUsbDebugControlled() {
        return !mPeripheralPolicy.isUsbDebuggingEnabled();
    }

    @Override
    public void controlRestoreFactory(boolean disabled) {
        gaPolicyManager.setFactoryResetPolicies(disabled ? 0 : 1);
    }

    @Override
    public boolean isRestoreFactoryControlled() {
        return gaPolicyManager.getFactoryResetPolicies() != 1;
    }

    @Override
    public void controlSystemUpgrade(boolean disabled) {
        if (!disabled) {
            boolean res = mPolicyManager.setSystemUpdatePolicies(1);
            Log.e(TAG, "release updatePhoneSystems via TD API res:" + res);
        } else {
            boolean res = mPolicyManager.setSystemUpdatePolicies(0);
            Log.e(TAG, "restrict updatePhoneSystems via TD API res:" + res);
        }
    }

    @Override
    public boolean isSystemUpgradeControlled() {
        int mode = mPolicyManager.getSystemUpdatePolicies();
        if (mode == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void controlGPS(boolean disabled) {

    }

    @Override
    public boolean setDisallowRunningApps(List<String> packageNames, boolean block) {
        if (block) {
            mPolicyManager.setRunAppPolicies(0, packageNames.toArray(new String[0]));
            CommonLogger.info("put " + packageNames.size() + " apps into system black policy.");
        } else {
            List<String> suspendPkgs = new ArrayList<>(Arrays.asList(mPolicyManager.getRunAppPolicies()));
            int removeCount = 0;
            for (String pkg : packageNames) {
                if (suspendPkgs.remove(pkg)) {
                    removeCount++;
                }
            }
            mPolicyManager.setRunAppPolicies(0, suspendPkgs.toArray(new String[0]));
            CommonLogger.info("release " + removeCount + " apps from system black policy");
        }
        return true;
    }

    @Override
    public List<String> getDisallowRunningApps() {
        List<String> result = new ArrayList<>();
        String[] policies = mPolicyManager.getRunAppPolicies();
        if (policies != null && policies.length > 0) {
            int mode = Integer.valueOf(policies[0]);
            List<String> systemBlackList = Arrays.asList(policies);
            if (mode == 0) {
                return systemBlackList;
            }
        }
        return result;
    }

    @Override
    public void installPackage(String apkPath) {
        try {
            mApplicationPolicy.installApplication(apkPath, false, new Handler(Looper.getMainLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    // install command is done
                    String packageName = parsePackageName(apkPath);
                    if (msg.what == -1) {
                        if (msg.arg1 != 1) {
                            CommonLogger.warn("install app via td failed : " + packageName);
                        }
                    }
                    CommonLogger.warn("install app via td success : " + packageName);
                }
            });
        } catch (Exception e) {
            CommonLogger.error("Silent install failed with TD API", e);
        }

        CommonLogger.info("install app via td " + apkPath);
    }

    @Override
    public void uninstallPackage(String packageName) {
        mApplicationPolicy.uninstallApplication(packageName, false, new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == -1) {
                    if (msg.arg1 != 1) {
                        CommonLogger.warn("uninstall app via td failed : " + packageName);
                    }
                }
                CommonLogger.warn("uninstall app via td success : " + packageName);
            }
        });
        CommonLogger.info("uninstall app via td " + packageName);
    }

    @Override
    public void formatSDCard() {
        //mdm No function
    }

    @Override
    public void factoryReset() {
        mSecurityPolicy.setFactoryReset(true);
    }

    @Override
    public void shutdown() {
        mSecurityPolicy.shutdown(false);
    }

    @Override
    public void reboot() {
        mSecurityPolicy.rebootDevice();
    }

    @Override
    public boolean setInstallSourceApps(List<String> packageNames) {
        return false;
    }

    @Override
    public List<String> getInstallSourceApps() {
        return null;
    }

    @Override
    public boolean setNetworkWhiteListApps(List<String> packageNames) {
        return false;
    }

    @Override
    public List<String> getNetworkWhiteListApps() {
        return null;
    }

    @Override
    public boolean setKeepLiveApps(List<String> packageNames) {
        return false;
    }

    @Override
    public List<String> getKeepLiveApps() {
        return null;
    }

    @Override
    public boolean setSuperApps(List<String> packageNames) {
        return false;
    }

    @Override
    public List<String> getSuperApps() {
        return null;
    }

    @Override
    public boolean setDevicePassword(String password) {
        if (TextUtils.isEmpty(password)) {
            boolean result = mPeripheralPolicy.setPasswordNone();
            CommonLogger.info("clear device password with result: " + result);
            return result;
        } else {
            int result = mPeripheralPolicy.setPassword(password);
            CommonLogger.info("change device password with result: " + result);
            return result == 0;
        }
    }

    @Override
    public String getName() {
        return "TD";
    }
}
